package com.su.lightthings.net

import android.content.Context
import android.location.LocationManager
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.su.lightthings.bluetooth.BtUtil
import com.su.lightthings.bluetooth.ProtocolDataUtil
import com.su.lightthings.utils.ByteUtils
import com.su.lightthings.utils.Cache
import com.su.lightthings.utils.Cons
import com.su.lightthings.viewmodel.BleViewModel
import com.su.lightthings.viewmodel.CommonViewModel
import okhttp3.OkHttpClient
import okhttp3.Request
import java.lang.ref.WeakReference
import java.math.RoundingMode
import java.text.DecimalFormat

object WeatherUtil {
    private const val TAG = "WeatherUtil"
    private val client = OkHttpClient()

    private var weakReference: WeakReference<AppCompatActivity>? = null

    fun setActivity(activity: AppCompatActivity) {
        weakReference = WeakReference(activity)
    }

    private fun getActivity(): AppCompatActivity? {
        return weakReference?.get()
    }

    fun getLatlng(): Pair<String, String> {
        val activity = weakReference?.get()

        val format = DecimalFormat("0.##")
        //未保留小数的舍弃规则，RoundingMode.HALF_DOWN表示四舍五入。
        format.roundingMode = RoundingMode.HALF_DOWN

        if (activity != null) {
            val locationManager =
                activity.getSystemService(Context.LOCATION_SERVICE) as LocationManager
            val provider = LocationManager.NETWORK_PROVIDER
            val hasPermission = (XXPermissions.isGranted(
                activity,
                Permission.ACCESS_FINE_LOCATION,
                Permission.ACCESS_COARSE_LOCATION
            ))
            if (hasPermission) {
                val location = locationManager.getLastKnownLocation(provider)
                if (location != null) {
                    Cache.lat = format.format(location.latitude)
                    Cache.lng = format.format(location.longitude)
                }
            }
        }
        return Pair(Cache.lat, Cache.lng)
    }


    //和风天气 https://dev.qweather.com/
    fun getWeather(all: Boolean, callBack: okhttp3.Callback) {
        val days = if (all) "7d" else "now"
        val (lat, lng) = getLatlng()
        Log.d(TAG, "location :  $lat  , $lng")
        val url =
            "https://devapi.qweather.com/v7/weather/$days?location=$lng,$lat&key=715fe233158841dcbe10e4ba73ffe32f"
        Log.d(TAG, "url: $url")
        val request = Request.Builder().url(url).build()
        client.newCall(request).enqueue(callBack)
    }

    fun getGeo(callBack: okhttp3.Callback) {
        val (lat, lng) = getLatlng()
        Log.d(TAG, "location :  $lat  , $lng")
        val url =
            "https://geoapi.qweather.com/v2/city/lookup?location=$lng,$lat&key=715fe233158841dcbe10e4ba73ffe32f"
        Log.d(TAG, "url: $url")
        val request = Request.Builder().url(url).build()
        client.newCall(request).enqueue(callBack)
    }

    fun hasPermission(): Boolean =
        getActivity()?.let {
            XXPermissions.isGranted(
                it,
                Permission.ACCESS_FINE_LOCATION,
                Permission.ACCESS_COARSE_LOCATION
            )
        } ?: false

    fun getPermission() {

    }

    private val commonViewModel = CommonViewModel.INSTANCE

    //发送实时天气
    fun sendCurrentWeatherToWatch() {
        val data = getCurrentWeatherData()
        if (data.isNotEmpty()) {
            Log.d(TAG, "发送实时天气：${ByteUtils.toHexString(data)}")
            BleViewModel.INSTANCE.write(data)
        }
    }

    //构建实时天气数据
    fun getCurrentWeatherData(): ByteArray {
        return if (commonViewModel.weather.rawWeatherBean != null
            && commonViewModel.futureWeather.rawWeatherBean != null
            && commonViewModel.zone.rawGeoBean != null
        ) {
            BtUtil.makeWriteData(
                functionId = Cons.PushFunctionId.WEATHER,
                data = ProtocolDataUtil.currentWeather(
                    commonViewModel.zone,
                    commonViewModel.weather,
                    commonViewModel.futureWeather,
                    System.currentTimeMillis()  //时间戳
                )
            )
        } else {
            byteArrayOf()
        }
    }

    //发送未来天气
    fun sendFutureWeatherToWatch() {
        val data = getFutureWeatherData()
        if (data.isNotEmpty()) {
            Log.d(TAG, "发送未来天气")
            BleViewModel.INSTANCE.write(data)
        }
    }

    //构建未来天气数据
    fun getFutureWeatherData(): ByteArray {
        return if (commonViewModel.weather.rawWeatherBean != null
            && commonViewModel.futureWeather.rawWeatherBean != null
            && commonViewModel.zone.rawGeoBean != null
        ) {
            BtUtil.makeWriteData(
                functionId = Cons.PushFunctionId.FUTURE_WEATHER,
                data = ProtocolDataUtil.futureWeather(
                    commonViewModel.zone,
                    commonViewModel.futureWeather
                )
            )
        } else {
            byteArrayOf()
        }
    }

    val handler = Handler(Looper.myLooper()!!)
    fun sendWeatherToWatch() {
        Log.d(TAG, "发送天气信息到手表")
        handler.post {
            sendCurrentWeatherToWatch()
        }
        handler.postDelayed({ sendFutureWeatherToWatch() }, 50)
    }

}